#ifndef _POKERHAND_H
#define _POKERHAND_H
//****************************************************************************
// File:    PokerHand.h
// Author:  Dr. Thomas C. Bressoud
// Date:    February 8, 2008
// Class:   CS 173-01, Professor Bressoud
// Purpose: Interface file for the PokerHand class, defining a hand of 5
//          cards drawn from a deck, with operations to deal into the hand,
//          query info about the cards in the hand, and to check for poker
//          hand category matching.
// Input:   NA
// Output:  NA
//****************************************************************************
#include <string>
using namespace std;

#include "Deck.h"
#include "Card.h"

class PokerHand {

public:
  //--------------------------------------------------------------------------
  // Constructors
  //
  PokerHand();                     // Default empty hand
  PokerHand(Deck & deck);          // Populate Hand from Deck
  PokerHand(const Card & c1,       // Create a hand explictly from five
            const Card & c2,       //   individual cards
            const Card & c3, 
            const Card & c4,
            const Card & c5);
  
  //--------------------------------------------------------------------------
  // Mutator functions
  //
  void dealAll(Deck & deck);       // Deal 5 cards from deck into hand
  void dealOne(Deck & deck);       // Deal single card from Deck into hand
  void reset();                    // Zero out hand
  
  //--------------------------------------------------------------------------
  // Accessor functions
  //
  Card getCard(int index)           const; // Return card at index
  Card::Suit getCardSuit(int index) const; // Return suit of card at index
  int getCardRank(int index)        const; // Return rank of card at index
  void rankCount(int * counts)      const; // Fills in array of counts with
                                           //   number of cards in that rank
                                           
  //--------------------------------------------------------------------------
  // Poker hand category query functions (also accessors)
  //
  bool isRoyalFlush()      const; // Ace high straight and all same suit
  bool isStraightFlush()   const; // Straight and all same suit
  int  isFourOfKind()      const; // Four cards of same rank
  bool isFullHouse()       const; // Three cards w/one rank and two w/another
  bool isFlush()           const; // All five same suit
  int  isStraight()        const; // Rank consecutive sequence with ace high
                                  //   or low
  int  isThreeOfKind()     const; // Three cards of same rank
  bool isTwoPair()         const; // Two cards w/one rank and two w/another
  int  isOnePair()         const; // Two cards w/one rank
  
  //---------------------------------------------------------------------------
  // String and Printing functions
  //
  string toString()        const; // Create string rep of entire hand
  void print()             const; // Output to std out entire hand
  
private:
    //--------------------------------------------------------------------------
    // Domain includes collection of cards number currently dealt into hand
    //   out of a maximum count of 5.
    //
    static const int COUNT = HAND_MAX;  // Private constant for size of a hand
    Card hand[COUNT];            // Array of cards forming the hand
    int ranks[RANK_MAX];
    int numInHand;               // Number of cards currently in the hand
    int leaderRank;

    bool _handIsFull()        const;
    void _rankCount_local();

    int _sameCardMaxCount();
    int _sameNumTimes(int) const;


}; // class PokerHand
#endif
